package org.xxpay.pay.channel.xx2pay;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.xxpay.core.common.domain.api.AbstractRes;
import org.xxpay.core.common.domain.api.ApiBuilder;
import org.xxpay.core.common.domain.api.PayRes;
import org.xxpay.core.common.domain.api.msg.QueryRetMsg;
import org.xxpay.core.common.util.DateUtil;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.common.util.PayDigestUtil;
import org.xxpay.core.common.util.XXPayUtil;
import org.xxpay.core.common.vo.DBApplicationConfig;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayment;
import org.xxpay.pay.util.Util;

import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

/**
 * @description: xxpay
 */
@Service
public class Xx2payPaymentService extends BasePayment {

    private static final MyLog _log = MyLog.getLog(Xx2payPaymentService.class);

    @Override
    public String getChannelName() {
        return Xx2payConfig.CHANNEL_NAME;
    }

    /**
     * 支付
     * @param payOrder
     * @return
     */
    @Override
    public AbstractRes pay(PayOrder payOrder) {
        _log.info("处理[xx2pay]渠道支付业务, payOrderId={}, channelId={}", payOrder.getPayOrderId(), payOrder.getChannelId());
        String channelId = payOrder.getChannelId();
        String productId = channelId.substring(channelId.indexOf("_")+1);
        return doPay(payOrder, productId);
    }

    private AbstractRes doPay(PayOrder payOrder, String productId) {

        Xx2payConfig xx2payConfig = new Xx2payConfig(getPayParam(payOrder));
        PayRes retObj = ApiBuilder.buildSuccess(PayRes.class);
        DBApplicationConfig dbConfig = getDBApplicationConfig();

        Map<String,Object> paramMap = new TreeMap();
        // 接口类型
        paramMap.put("mchId", xx2payConfig.getMchId());
        paramMap.put("appId", xx2payConfig.getAppId());
        paramMap.put("productId", productId); //支付产品
        paramMap.put("mchOrderNo", payOrder.getPayOrderId());
        paramMap.put("amount", payOrder.getAmount() + "");
        paramMap.put("currency", "cny");
        paramMap.put("clientIp", StringUtils.isBlank(payOrder.getClientIp()) || "null".equalsIgnoreCase(payOrder.getClientIp()) ? Util.getRandomIp() : payOrder.getClientIp());
        paramMap.put("device", "web");
        paramMap.put("returnUrl", super.getReturnUrl(getChannelName(), dbConfig));
        paramMap.put("notifyUrl", super.getNotifyUrl(getChannelName(), dbConfig));
        paramMap.put("subject", payOrder.getSubject());
        paramMap.put("body", payOrder.getBody());
        paramMap.put("reqTime", DateUtil.date2Str(new Date(), DateUtil.FORMAT_YYYYMMDDHHMMSS));
        paramMap.put("version", "1.0");

        // 签名
        String sign = PayDigestUtil.getSign(paramMap, xx2payConfig.getKey());
        paramMap.put("sign", sign);

        String reqUrl = xx2payConfig.getReqUrlHost() + "/api/pay/create_order?" + XXPayUtil.genUrlParams(paramMap);
        _log.info("请求[xx2pay], 请求数据:{}", reqUrl);
        String resData = XXPayUtil.call4Post(reqUrl);
        _log.info("请求[xx2pay], 返回结果:{}", resData);
        if(StringUtils.isEmpty(resData)){
            _log.error("请求[xx2pay]渠道支付中心返回结果为空， reqUrl={}", reqUrl);
            return ApiBuilder.bizError("请求渠道支付中心下单失败");
        }

        JSONObject resDataJSON = JSONObject.parseObject(resData);
        if(!"0".equals(resDataJSON.getString("retCode"))){
            _log.error("请求[xx2pay]渠道支付中心返回结果异常， resDataJSON={}", resDataJSON.toJSONString());
            return ApiBuilder.bizError("请求渠道支付中心下单失败");
        }

        if(!XXPayUtil.verifyPaySign(resDataJSON, xx2payConfig.getKey())){
            return ApiBuilder.bizError("验证签名失败");
        }

        int updateCount = commonService.payOrderService.updateStatus4Ing(payOrder.getPayOrderId(), resDataJSON.getString("payOrderId"));
        _log.info("[{}]更新订单状态为支付中:payOrderId={},result={}", getChannelName(), payOrder.getPayOrderId(), updateCount);

        retObj.setJumpInfo(resDataJSON.getString("payUrl"), resDataJSON.getString("payJumpUrl"));
        return retObj;
    }

    /**
     * 查询订单
     * @param payOrder
     * @return
     */
    @Override
    public QueryRetMsg query(PayOrder payOrder) {
        Xx2payConfig xx2payConfig = new Xx2payConfig(getPayParam(payOrder));

        JSONObject retObj = new JSONObject();

        Map<String,Object> paramMap = new TreeMap();
        // 接口类型
        paramMap.put("mchId", xx2payConfig.getMchId());
        paramMap.put("appId", xx2payConfig.getAppId());
        paramMap.put("mchOrderNo", payOrder.getPayOrderId());
        paramMap.put("reqTime", DateUtil.date2Str(new Date(), DateUtil.FORMAT_YYYYMMDDHHMMSS));
        paramMap.put("version", "1.0");

        // 签名
        String sign = PayDigestUtil.getSign(paramMap, xx2payConfig.getKey());
        paramMap.put("sign", sign);

        String reqUrl = xx2payConfig.getReqUrlHost() + "/api/pay/query_order?" + XXPayUtil.genUrlParams(paramMap);
        String resData = XXPayUtil.call4Post(reqUrl);

        if(StringUtils.isEmpty(resData)){
            _log.error("请求[xx2pay]渠道支付中心返回结果为空， reqUrl={}", reqUrl);
            return QueryRetMsg.waiting();  //支付中
        }

        JSONObject resDataJSON = JSONObject.parseObject(resData);
        if(!"0".equals(resDataJSON.getString("retCode"))){
            _log.error("请求[xx2pay]渠道支付中心查单业务返回结果异常， resDataJSON={}", resDataJSON.toJSONString());
            return QueryRetMsg.confirmSuccess(null);  // 成功
        }

        if(!XXPayUtil.verifyPaySign(resDataJSON, xx2payConfig.getKey())){
            return QueryRetMsg.waiting();  //支付中
        }
        String status = resDataJSON.getString("status");
        if("2".equals(status) || "3".equals(status)) {
            return QueryRetMsg.confirmSuccess(null);  // 成功
        }
        return QueryRetMsg.waiting();  //支付中
    }

}
